﻿/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
FileApi = function() {
    alert("here0");
    this.persistence = {};
    this.fileSystemObj = new FileSystem();
	alert("here");
	if (!this.fileSystemObj.isValidCommonPath(curWidget.id))
	{
	   this.fileSystemObj.createCommonDir(curWidget.id);
	   alert("here2");
	}
    var fileObj = this.fileSystemObj.openCommonFile(curWidget.id + "/persistence.json", 'r');
	alert("here3");
    if (fileObj)
    {
	    alert("here4");
		var storage = fileObj.readAll();
		alert(storage);
		if (storage)
		{
        this.persistence = JSON.parse(storage);
		alert("here5");
		}
        this.fileSystemObj.closeCommonFile(fileObj);
    }
	alert("here6");
};
FileApi.prototype = {
    getServerDetails: function() {
        return this.persistence.serverDetails;
    },
    setServerDetails: function(serverDetails) {
        this.persistence.serverDetails = serverDetails;
		alert("setServerDetails "+ this.persistence.serverDetails);
    },
    getPassword: function() {
        return this.persistence.password;
    },
    setPassword: function(password) {
        this.persistence.password = password;
		alert("setPassword "+ this.persistence.password);
    },
    getBreadcrumb: function() {
        this.persistence.breadcrumb;
    },
    persist: function() {
	    if (!this.fileSystemObj.isValidCommonPath(curWidget.id))
		{
		   this.fileSystemObj.createCommonDir(curWidget.id);
		}
        var fileObj = this.fileSystemObj.openCommonFile(curWidget.id + "/persistence.json", 'w');
		if (this.persistence)
		{
		   alert("persisting "+this.persistence);
        fileObj.writeAll(JSON.stringify(this.persistence));
		}
        this.fileSystemObj.closeCommonFile(fileObj);
    }
};

function Folder()
{
    var title;
    var logicalFolder;
    var childCount;
}
;

ServiioStateMachine = function(fileApi) {
    this.fileApi = fileApi;
    this.serverDetails;
    this.authToken = null;
    this.baseFolders = null;
    this.breadcrumb = null;
    this.selectionIndex = -1;
};
ServiioStateMachine.prototype = {
    onstarting: function(event, from, to) {
        var localServerDetails = this.fileApi.getServerDetails();
        var password = this.fileApi.getPassword();
        // if not set we get these back as undefined
		alert("attempting logon "+localServerDetails+ " "+password);
        if (null == localServerDetails || null == password)
        {
            this.noConnection();
            return;
        }
        var date = dateFormat(new Date(), "ddd, dd mmm yyyy  HH:MM:ss Zo");
        var hmacBytes = Crypto.HMAC(Crypto.SHA1, date, password, {
            asBytes: true
        });
        var token = Crypto.util.bytesToBase64(hmacBytes);
        var me = this;
        jQuery.support.cors = true;
		
        jQuery.ajax({
            url: "http://" + localServerDetails + "/cds/login",
            dataType: 'json',
            async: true,
            type: 'POST',
            xhrFields: {
                withCredentials: false
            },
            headers: {
                'X-Serviio-Date': date,
                'Authorization': 'Serviio ' + token
            },
            success: function(data) {
                me.authToken = data.parameter;
                me.serverDetails = localServerDetails;
                me.connected();
            },
            error: function(error) {
                me.noConnection();
            }
        });
    },
    onworking: function(event, from, to)
    {
		this.fileApi.persist();
    },
    onbeforesetDetails: function(event, from, to, args)
    {
	    alert("set details "+args[0]+ " "+ args[1]);
        this.fileApi.setServerDetails(args[0]);
        this.fileApi.setPassword(args[1]);
    },
    onsearching: function(event, from, to)
    {
        // how many queries to I send out?
        if (!this.basefolders)
        {
            var baseFolderSearchURL = "http://" + serverDetails + "/cds/browse/flv_player/0/BrowseDirectChildren/containers/0/0?authToken=" + this.authToken;
            var me = this;
            jQuery.ajax({
                url: baseFolderSearchURL,
                dataType: 'json',
                async: true,
                type: 'GET',
                success: function(data) {
                    me.result(data);
                },
                error: function() {
                    me.noConnection();
                }
            });
        }
    },
    onbreadcrumbResult: function(event, from, to, data)
    {
        // add to breadcrumb, or is this a new result?
        if (this.selectionIndex < 0)
        {
            this.breadcrumb = data.length ? data : [data];
            this.selectionIndex = data.length ? data.length - 1 : 0;
            this.breadcrumbSelections = [0];
        }
        else
        {
            // assume its an append
            if (!this.breadcrumb)
            {
                this.breadcrumb = new Array();

            }
            if (data.options && data.options.length > 0)
            {
                this.breadcrumb.push(data);
                this.selectionIndex++;
            }
        }
    },
    onbeforestartContentSearch: function(event, from, to)
    {
        // shouldn't really do actions here!
        if (to === 'breadcrumbSelect')
        {
            return null !== this.getBreadcrumb();
        }
        else if (to === 'breadcrumbWaitingOnResult')
        {
            return !this.getBreadcrumb();
        }
    },
    onbreadcrumbWaitingOnResult: function(event, from, to)
    {
        // start a search#
        if (this.breadcrumb)
        {
            // what search folder so I want?
            var selectedFolder = this.breadcrumb[this.selectionIndex].selectionIndex;
            var folder = this.breadcrumb[this.selectionIndex].options[selectedFolder];
            this.folderSearch(folder.logicalFolder);
        }
        else
        {
            // try the file system
            var storedBreadcrumb = this.fileApi.getBreadcrumb();
            // really shouldn't modify the statemachine state 
            if (!storedBreadcrumb)
            {
                this.folderSearch(0);
            }
            else
            {
                this.breadcrumbResult(JSON.parse(storedBreadcrumb));
            }
        }

    },
    folderSearch: function(folderIndex) {
        var me = this;
        var baseFolderSearchURL = "http://" + this.serverDetails + "/cds/browse/flv_player/" + folderIndex + "/BrowseDirectChildren/containers/0/0?authToken=" + this.authToken;
        jQuery.ajax({
            url: baseFolderSearchURL,
            dataType: 'json',
            async: true,
            type: 'GET',
            success: function(data) {
                // parse the response into breadcrumb, then fire the result
                var currentBreadcrumbOptions = me.parseBreadcrumb(data);
                me.breadcrumbResult(currentBreadcrumbOptions);
            },
            error: function() {
                me.noConnection();
            }
        });
    },
    parseBreadcrumb: function(data) {
        var results = new Array();
        for (var index = 0; index < data.objects.length; index++)
        {
            var member = data.objects[index];
            if (member.type === 'CONTAINER')
            {
                var folder = new Folder();
                folder.title = member.title;
                folder.logicalFolder = member.id;
                folder.childCount = member.childCount;
                results.push(folder);
            }
        }
        var breadcrumbItem = {};
        breadcrumbItem.options = results;
        breadcrumbItem.selectionIndex = 0;
        return breadcrumbItem;
    },
    getBreadcrumb: function()
    {
        return this.breadcrumb;
    },
    oninitialContentSearch: function(event, from, to) {
        var me = this;
        var startIndex = 0;
        var maxItems = 0; // all
        var folder = this.breadcrumb[this.selectionIndex].options[this.breadcrumb[this.selectionIndex].selectionIndex];
        var folderIndex = folder.logicalFolder;

        var baseFolderSearchURL = "http://" + this.serverDetails + "/cds/browse/flv_player/" + folderIndex + "/BrowseDirectChildren/containers/" + startIndex + "/" + maxItems + "?authToken=" + this.authToken;
        jQuery.ajax({
            url: baseFolderSearchURL,
            dataType: 'json',
            async: true,
            type: 'GET',
            success: function(data) {
                // parse the response into breadcrumb, then fire the result
                var currentBreadcrumbOptions = me.parseContent(data);
                me.contentResult(currentBreadcrumbOptions);
            },
            error: function() {
                me.noConnection();
            }
        });
    },
    parseContent: function(data) {
        var results = new Array();
        var folders = new Array();
        var itemsInSearch = data.totalMatched; // includes those beyond the number requested
        // pages...  page 1 (from 0..20 'items')... need which folders and how many items in each folder..
        // so need to determine how many folders in current search... and items... items first...
        // split into page.folder[0].startIndex... page.folder[0].endIndex.. stop when page Count>10 (assume user will be bored)

        for (var index = 0; index < data.objects.length; index++)
        {
            var member = data.objects[index];
            if (member.type === 'CONTAINER')
            {
                var folder = new Folder();
                folder.title = member.title;
                folder.logicalFolder = member.id;
                folder.childCount = member.childCount;
                folders.push(folder);
            }
            else if (member.type === 'ITEM')
            {
                var item = {};
                item.title = member.title;
                item.type = member.fileType;
                item.thumbnailUrl = member.thumbnailUrl;
                item.contentUrl = member.contentUrls[0].url; // search for quality!
                item.onlineIdentifiers = member.onlineIdentifiers;
                item.summary = member.description;
                results.push(item);
            }
        }
        return results;

    },
    ondown: function(event, from, to) {
        if (from === 'breadcrumbSelect')
        {
            if (this.breadcrumb[this.selectionIndex].options.length - 1 > this.breadcrumb[this.selectionIndex].selectionIndex)
            {
                this.breadcrumb[this.selectionIndex].selectionIndex += 1;

            }
            else
            {
                this.breadcrumb[this.selectionIndex].selectionIndex = 0;
            }
        }
    },
    onup: function(event, from, to) {
        if (from === 'breadcrumbSelect')
        {
            if (this.breadcrumb[this.selectionIndex].selectionIndex === 0)
            {
                this.breadcrumb[this.selectionIndex].selectionIndex = this.breadcrumb[this.selectionIndex].options.length - 1;
            }
            else
            {
                this.breadcrumb[this.selectionIndex].selectionIndex -= 1;
            }
        }
    },
    onleft: function(event, from, to) {
        if (from === 'breadcrumbSelect' && this.selectionIndex > 0)
        {
            // I'm assigning this here as this should flag the item as going out of scope and allow memmory to be regained
            var itemRemoved = this.breadcrumb.pop();
            this.selectionIndex--;
        }
    },
    onright: function(event, from, to) {

    },
    onselect: function(event, from, to) {

    }
};
StateMachine.create({
    target: ServiioStateMachine.prototype,
    events: [
        {name: 'startup', from: 'none', to: 'starting'},
        {name: 'noConnection', from: 'starting', to: 'noDetails'},
        {name: 'setDetails', from: 'noDetails', to: 'starting'},
        {name: 'connected', from: 'starting', to: 'working'},
        {name: 'startContentSearch', from: 'working', to: ['breadcrumbWaitingOnResult', 'breadcrumbSelect']},
        {name: 'breadcrumbResult', from: 'breadcrumbWaitingOnResult', to: 'breadcrumbSelect'},
        {name: 'select', from: 'breadcrumbSelect', to: 'initialContentSearch'},
        {name: 'down', from: 'breadcrumbSelect', to: 'breadcrumbSelect'},
        {name: 'up', from: 'breadcrumbSelect', to: 'breadcrumbSelect'},
        {name: 'right', from: 'breadcrumbSelect', to: 'breadcrumbWaitingOnResult'},
        {name: 'left', from: 'breadcrumbSelect', to: ['breadcrumbSelect']},
        {name: 'contentResult', from: 'initialContentSearch', to: ['initialContentSearch', 'selectContent']},
        {name: 'up', from: 'selectContent', to: ['breadcrumbSelect', 'selectContent']},
        {name: 'down', from: 'selectContent', to: ['selectContent', 'contentSearching']},
        {name: 'select', from: 'selectContent', to: 'selectContent'},
        {name: 'right', from: 'selectContent', to: ['contentSearching', 'selectContent']},
        {name: 'left', from: 'selectContent', to: ['contentSearching', 'selectContent']},
        {name: 'contentResult', from: 'contentSearching', to: ['contentSearching', 'selectContent']}
    ]
});